package ac.svn.accesscontrol.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;

import ac.notification.event.INotificationListener;
import ac.notification.event.NotificationEvent;
import ac.notification.manager.NotificationRegistrar;
import ac.svn.accesscontrol.manager.SVNInfoManager;
import ac.svn.accesscontrol.store.Dictionary;
import ac.svn.accesscontrol.store.IResources;
import ac.svn.accesscontrol.store.ISVNIdentifier;
import ac.svn.accesscontrol.store.ISVNItem;
import ac.svn.accesscontrol.store.SVNGroup;
import ac.svn.accesscontrol.store.SVNLocation;
import ac.svn.accesscontrol.store.SVNUser;
import ac.svn.accesscontrol.ui.ContentLister;
import ac.svn.accesscontrol.ui.IUIConstants;
import ac.svn.accesscontrol.ui.LocationFilter;
import ac.svn.accesscontrol.ui.LocationFilterByUser;
import ac.svn.accesscontrol.ui.MainWindow;
import ac.svn.accesscontrol.ui.SVNItemFilter;
import ac.svn.accesscontrol.ui.TreePopulator;
import ac.svn.accesscontrol.ui.UIComponentLibrary;
import ac.svn.accesscontrol.utils.Utility;

public class UIController implements INotificationListener,ISVNIdentifier,IUIConstants{

	private JLabel statusLabel;
	private ContentLister locationLister;
	private ContentLister accessLister;
	private TreePopulator treePopulator;
	private SVNItemFilter itemFilter;
	private JTextField userSearchTxt;
	private JTextField locationSearchTxt;
	private LocationFilter locationFilter;
	private SVNInfoManager infoManager;
	private LocationFilterByUser filterByUser;
	
	private Set<String> subscriptions;
	private JMenu actionMenu;
	private JMenuItem reloadMI;
	private JList locationListView;
	private JTree svnTree;
	private MainWindow mainWindow;
	
	public UIController()
	{
		subscriptions = new HashSet<String>();
		locationListView = (JList) UIComponentLibrary.getComponent(C_LOCATION_LIST);
		mainWindow = (MainWindow) UIComponentLibrary.getComponent(C_MAIN_WINDOW);

		svnTree = (JTree) UIComponentLibrary.getComponent(C_USERS_TREE);
		
		treePopulator = new TreePopulator(C_USERS_TREE, C_ROOT_NODE);
		treePopulator.setListClrRequired(true);
		locationLister 	= new ContentLister(C_LOCATION_LIST, C_LOCATION_MODEL);
		locationLister.setListClrRequired(true);
		accessLister = new ContentLister(C_ACCESS_LIST, C_ACCESS_MODEL);
		accessLister.setListClrRequired(true);
		
		filterByUser = new LocationFilterByUser(C_LOCATION_LIST, C_LOCATION_MODEL);
		
		itemFilter = new SVNItemFilter();
		locationFilter = new LocationFilter(C_LOCATION_LIST, C_LOCATION_MODEL);
		
		userSearchTxt =  (JTextField) UIComponentLibrary.getComponent(C_TEXT_S_USER);
		locationSearchTxt =  (JTextField) UIComponentLibrary.getComponent(C_TEXT_S_LOCATION);
		

		statusLabel = (JLabel) UIComponentLibrary.getComponent(C_STATUS_LABEL);
		
		actionMenu = (JMenu) UIComponentLibrary.getComponent(M_ACTION_MENU);
		reloadMI = new JMenuItem("Reload");
		actionMenu.add(reloadMI);
		infoManager = SVNInfoManager.getInfoManager();
		NotificationRegistrar.registerListener(this);

		registerListeners();
	}




	private void registerListeners() {
		
		userSearchTxt.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent arg0) {
				SwingUtilities.invokeLater(new Runnable() {
					
					@Override
					public void run() {
						String searchString = userSearchTxt.getText();
						if(null != searchString && !searchString.isEmpty() && searchString.length() > 0)
						{
							itemFilter.findNode(searchString.toLowerCase());
						}
						else
						{
							itemFilter.clearSelection();
						}
					}
				});
			}
		});
		
		locationSearchTxt.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent arg0) {
				SwingUtilities.invokeLater(new Runnable() {
					
					@Override
					public void run() {
						locationFilter.filterList(infoManager.getAllLocations(), locationSearchTxt.getText());
					}
				});
			}
		});
		
		locationListView.addListSelectionListener(new ListSelectionListener() {

			@Override
			public void valueChanged(ListSelectionEvent lse) {
				if(!lse.getValueIsAdjusting())
				{
					SVNLocation location = (SVNLocation) locationListView.getSelectedValue();
					if(null == location)
					{
						return;
					}
					NotificationEvent ne = new NotificationEvent(N_UPDATE_ACCESS);
					ne.setPropertyValue(location.getLocationPath());
					NotificationRegistrar.dispatchNotification(ne);;
				}
			}
		});

		reloadMI.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				refresh();
			}
		});


		mainWindow.getRootPane().registerKeyboardAction(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				refresh();
			}},
		KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0),
		JComponent.WHEN_IN_FOCUSED_WINDOW);
		
		mainWindow.getRootPane().registerKeyboardAction(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				mainWindow.setExtendedState(JFrame.MAXIMIZED_BOTH);
			}},
		KeyStroke.getKeyStroke(KeyEvent.VK_F6, 0),
		JComponent.WHEN_IN_FOCUSED_WINDOW);
		
		mainWindow.getRootPane().registerKeyboardAction(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				userSearchTxt.requestFocus();
			}},
		KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0),
		JComponent.WHEN_IN_FOCUSED_WINDOW);
		
		mainWindow.getRootPane().registerKeyboardAction(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				locationSearchTxt.requestFocus();
			}},
		KeyStroke.getKeyStroke(KeyEvent.VK_F4, 0),
		JComponent.WHEN_IN_FOCUSED_WINDOW);
		
		
		svnTree.addMouseListener(new MouseListener() {
			
			@Override
			public void mouseReleased(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mousePressed(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mouseExited(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mouseEntered(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void mouseClicked(MouseEvent arg0) {
				DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) svnTree.getSelectionPath().getLastPathComponent();
				ISVNItem svnItem = (ISVNItem) selNode.getUserObject();
				if(svnItem instanceof SVNUser)
				{
					filterByUser.filterListByUser(svnItem.getName());				
				}
				else
				{
					filterByUser.filterListByGroup(svnItem.getName());	
				}
			}
		});
	}
	
	
	




	@Override
	public Set<String> declaredSubscriptionSet() {
		subscriptions.add(N_UPDATE_USERS);
		subscriptions.add(N_UPDATE_ACCESS);
		return subscriptions;
	}

	@Override
	public void receiveEvent(NotificationEvent ne) {
		if(ne.getPropertyIdentifier().contains(N_UPDATE_USERS))
		{
			treePopulator.listItem(infoManager.getAllGroups());
			locationLister.listItem(infoManager.getAllLocations()); 
		}
		else if(ne.getPropertyIdentifier().contains(N_UPDATE_ACCESS))
		{
			String locationPath = (String) ne.getPropertyValue();
			SVNLocation location = infoManager.getLocation(locationPath);
			accessLister.listItem(location.getAccessUnits());
		}

	}

	private void refresh()
	{
		statusLabel.setText("Reloading file..");
		statusLabel.setIcon(Utility.getImageIcon(IResources.LOC_ICN_REFRESH));
		for(ISVNItem isvnItem : SVNInfoManager.getInfoManager().getAllGroups())
		{
			SVNGroup svnGroup = (SVNGroup) isvnItem;
			UIComponentLibrary.removeComponent(svnGroup.getGroupAlias());
		}				
		SVNInfoManager.getInfoManager().clearAll();

		NotificationEvent event = new NotificationEvent(ISVNIdentifier.CMD_PROCESS_FILE);
		event.setPropertyValue(Dictionary.getCurrentAccessFile());
		NotificationRegistrar.dispatchNotification(event)	;
	}
}
